'''
Created on April 2, 2011

iur - Universal Web Remote targetted for iphone
Copyright (C) 2010 forteresce@gmail.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

'''

from player.eventhandler import PlayerEventHandler
from model.song import Song
from model.playlist import Playlist
from util.utils import DBusInterface
from util.mpris import MPRIS2_DBUS_PLAYER, MPRIS2_DBUS_OBJECT, MPRIS2_DBUS_PLAYLISTS
import base64
import urlparse
import dbus
import urllib


class GenericEventHandler(PlayerEventHandler):
    
    canBeControlled = True
    
    def __init__(self, service):
        self.dbusName = service
        self.mpris2Player = DBusInterface(service, MPRIS2_DBUS_OBJECT,MPRIS2_DBUS_PLAYER)
        self.mpris2Playlists = DBusInterface(service, MPRIS2_DBUS_OBJECT, MPRIS2_DBUS_PLAYLISTS)
        self.canBeControlled = self.canControl()
        pass

#===============Player Interface=========================
#==================Methods============================
   
    def next(self):
        if self.canBeControlled and self.canGoNext():
            self.mpris2Player.Next()
            
    def prev(self):
        if self.canBeControlled and self.canGoPrevious():
            self.mpris2Player.Previous()    
    
    def pause(self):
        if self.canBeControlled and self.canPause():
            self.mpris2Player.Pause()
        
    def togglePlaying(self):
        if self.canBeControlled and (self.canPlay() or self.canPause()):
            self.mpris2Player.PlayPause()
         
    def stop(self):
        if self.canBeControlled:
            self.mpris2Player.Stop()
         
    def play(self):
        if self.canBeControlled and self.canPlay():
            self.mpris2Player.Play()
            
    def seek(self, value):
        if self.canBeControlled and self.canSeek():
            self.mpris2Player.Seek(dbus.Int64(value))
            
    def setPosition(self, trackId, position):
        if self.canBeControlled:
            self.mpris2Player.SetPosition(dbus.ObjectPath(trackId), dbus.Int64(position))
    
    def openUri(self, uri):
        if self.canBeControlled:
            self.mpris2Player.OpenUri(dbus.String(uri))

#==================Properties============================
    def getPlaybackStatus(self):
        return self.mpris2Player.get('PlaybackStatus')
    
    def getLoopStatus(self):
        return self.mpris2Player.get('LoopStatus')
    
    def setLoopStatus(self, value):
        if self.canBeControlled:
            self.mpris2Player.set('LoopStatus', dbus.String(value))
        
    def getRate(self):
        return self.mpris2Player.get('Rate')
    
    def setRate(self, value):
        if not self.canBeControlled:
            return
        #Check value is between the limit
        if value > self.getMaximumRate() or value < self.getMinumumRate() or value == 0:
            return
        self.mpris2Player.set('Rate', dbus.Double(value))   
    
    def getShuffle(self):
        return bool(self.mpris2Player.get('Shuffle'))
    
    def setShuffle(self, value):
        if self.canBeControlled:
            self.mpris2Player.set('Shuffle', dbus.Boolean(value))   
        
    def getMetadata(self):
        return self.mpris2Player.get('Metadata')
             
    def setVolume(self, value):
        if not self.canBeControlled:
            return
        
        if value > 1:
            value = 1
        elif value <0:
            value = 0
        self.mpris2Player.set('Volume', dbus.Double(value))
        
    def getVolume(self):
        return self.mpris2Player.get('Volume')
            
    def getPosition(self):
        return self.mpris2Player.get('Position')
    
    def getMinumumRate(self):
        return self.mpris2Player.get('MinumumRate')
    
    def getMaximumRate(self):
        return self.mpris2Player.get('MaximumRate')
    
    def canGoNext(self):
        return bool(self.mpris2Player.get('CanGoNext'))
    
    def canGoPrevious(self):
        return bool(self.mpris2Player.get('CanGoPrevious'))
 
    def canPlay(self):
        return bool(self.mpris2Player.get('CanPlay'))   
    
    def canPause(self):
        return bool(self.mpris2Player.get('CanPause'))
    
    def canSeek(self):
        return bool(self.mpris2Player.get('CanSeek'))
    
    def canControl(self):
        return bool(self.mpris2Player.get('CanControl'))
    
#==================Playlists Interface========================
#=====================Methods=============================
    def activatePlaylist(self, id):
        self.mpris2Playlists.ActivatePlaylist(dbus.ObjectPath(id))
    
    def getPlaylists(self, index, count, order, reverseOrder):
        return self.mpris2Playlists.GetPlaylists(dbus.Int32(index), dbus.Int32(count), dbus.String(order), dbus.Boolean(reverseOrder))

#=====================Properties=============================
    def getPlaylistCount(self):
        return self.mpris2Playlists.get('PlaylistCount')
 
    def getOrderings(self):
        return self.mpris2Playlists.get('Orderings')
    
    def getActivePlaylist(self):
        return self.mpris2Playlists.get('ActivePlaylist')
    
#==================Extended Functions============================
    def getCurrentSong(self):
        if self.getPlaybackStatus() == 'Stopped':
            return
        
        track = self.getMetadata()
        
        # clean up
        vals = ('xesam:title', 'xesam:album', 'xesam:artist', 'mpris:artUrl')
        for key in [key for key in vals if key not in track]:
            track[key] = 'Unknown'
        
        return Song(track['xesam:title'], track['xesam:artist'], track['xesam:album'], urlparse.urlparse(urllib.url2pathname(track['mpris:artUrl'])).path)

    def volumeUp(self):
        volume = self.getVolume() + 0.1
        self.setVolume(volume)
        return self.getVolume()

    def volumeDown(self):
        volume = self.getVolume() - 0.1
        self.setVolume(volume)
        return self.getVolume()
    
    def playSong(self, id):
        uri = base64.b64decode(id)
        self.openUri(uri)
        
    def seekForward(self):
        self.seek(100000)
        return self.getPosition()
        
    def seekBackward(self):
        self.seek(-100000)
        return self.getPosition()
    
    def getPlayerPlaylists(self):
        playlists = []
        pl = self.getPlaylists(0, self.getPlaylistCount(), "Alphabetical", False)
        for (id, name, icon) in pl:
            playlist = Playlist(base64.b64encode(id), name, icon)
            playlists.append(playlist)
        return playlists    
    
    def getCurrentPlaylist(self):
        pl = self.getActivePlaylist()
        for (valid, (id, name, icon)) in pl:
            if bool(valid):
                playlist = Playlist(base64.b64encode(id), name, icon)
                return playlist
            else:
                return
       
    def setCurrentPlaylist(self, id): 
        self.activatePlaylist(base64.b64decode(id))

    def playSong(self, id): 
        uri=base64.b64decode(id)
        self.openUri(uri)
 
